package com.mdms.commands.dictionaries;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.hibernate.Hibernate;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import com.mdms.commands.BaseCommand;
import com.mdms.commands.user.UserCommand;
import com.mdms.dto.MdmDctAttributes;
import com.mdms.dto.MdmDictionaries;
import com.mdms.dto.UdtUsers;
import com.mdms.interfaces.orm.CrudDAO;
import com.mdms.logger.SimplyMDLogger;

public class DictionariesCommand extends BaseCommand {

	private final static SimplyMDLogger logger = new SimplyMDLogger(DictionariesCommand.class);
	private static final long serialVersionUID = 1L;

	public final static String GET_ALL_DICTIONARIES = "GET_ALL_DICTIONARIES";

	public final static String GET_DICTIONARY_BY_ID = "GET_DICT_BY_ID";

	public final static String GET_DICTIONARY_BY_TYPE_AND_CODE = "GET_DICT_BY_CODE_TYPE";

	public final static String GET_DICTIONARY_LIST_BY_TYPE = "GET_DICT_BY_LIST_TYPE";

	public final static String GET_DICT_ATTR_BY_ID = "GET_DICT_ATTR_BY_ID";

	public final static String GET_DICT_ATTR_BY_TYPE_CODE = "GET_DICT_ATTR_BY_CODE_TYPE";

	public final static String SAVE_DICT = "SAVE_DICT";

	public final static String SAVE_DICT_ATT = "SAVE_DICT_ATT";

	private String action;

	private Long dictId;

	private String dctType;

	private String dctCode;

	private String dctAttrName;

	private MdmDictionaries mdmDictionaries;

	private MdmDctAttributes mdmAttributes;

	private List<MdmDictionaries> mdmDictList;


	private boolean getAttributes = true;


	@Override
	public void execute() throws Exception {
		logger.debug("execute", "START");
		if(action.equals(GET_ALL_DICTIONARIES)){
			getAllDict();
		}else if(action.equals(GET_DICTIONARY_BY_ID)){
			getDictById();
		}else if(action.equals(GET_DICTIONARY_BY_TYPE_AND_CODE)){
			getDictByTypeCode();
		}else if(action.equals(GET_DICT_ATTR_BY_ID)){
			getAttrById();
		}else if(action.equals(GET_DICT_ATTR_BY_TYPE_CODE)){
			getAttrByCodeType();
		}else if (action.equals(GET_DICTIONARY_LIST_BY_TYPE)){
			getDictListByType();
		}else if (action.equals(SAVE_DICT)){
			saveDict();
		}else if (action.equals(SAVE_DICT_ATT)){
			saveAttr();
		}else{
			logger.error("execute", "Action name is empty or is not recognized");
		}

		logger.debug("execute", "END");
	}

	protected void getAllDict(){
		String methodName="getAllDictionaries";
		logger.debug(methodName, "START");
		try{
			CrudDAO crudDAO = getDaoFactory().getCrudDAO();
			crudDAO.setPersistentClass(MdmDictionaries.class);
			Transaction tx=crudDAO.beginTransaction();
			mdmDictList=new ArrayList<MdmDictionaries>();
			mdmDictList=crudDAO.findAll();

			if(mdmDictList.isEmpty()){
				setErrorCode(-1);
				setErrorDesc("Dictionaries not found");
				return ;
			}
			for (MdmDictionaries dict : mdmDictList) {
				Hibernate.initialize(dict.getMdmDictionaries());
				if(getAttributes){
					for (MdmDctAttributes attributes : (Set<MdmDctAttributes>)dict.getMdmDctAttributeses()) {
						Hibernate.initialize(attributes);
					}
				}
			}
			tx.commit();
			logger.debug(methodName, "Getting Dictionaries from DB succes. Dictionaries download : " +mdmDictList.size());

		}catch(Exception e){
			setErrorCode(-1);
			setErrorDesc(e.getMessage());
		}
		logger.debug(methodName, "END");
	}

	protected void getDictById(){
		String methodName="getDictionarieyById";
		try{
			CrudDAO crudDAO = getDaoFactory().getCrudDAO();
			crudDAO.setPersistentClass(MdmDictionaries.class);
			Transaction tx=crudDAO.beginTransaction();
			if(dictId!=null && !dictId.equals(0)){
				setErrorCode(-2);
				setErrorDesc("Dictionary id is null or equal 0");
				return ;
			}
			mdmDictionaries=(MdmDictionaries)crudDAO.findById(dictId);
			if(mdmDictionaries==null){
				setErrorCode(-1);
				setErrorDesc("Dictionary id: " + dictId.toString()+ "not found");
				return ;
			}
			Hibernate.initialize(mdmDictionaries.getMdmDictionaries());
			if(getAttributes){
				for (MdmDctAttributes attributes : (Set<MdmDctAttributes>)mdmDictionaries.getMdmDctAttributeses()) {
					Hibernate.initialize(attributes);
				}
			}
			tx.commit();
			logger.debug(methodName, "Getting Dictionariey id: "+ dictId.toString() +"from DB succes");
		}catch(Exception e){
			setErrorCode(-1);
			setErrorDesc(e.getMessage());
		}
		logger.debug(methodName, "START");
		logger.debug(methodName, "END");
	}

	protected void getDictByTypeCode(){
		String methodName="getDictionarieyByCodeAndType";
		try{
			CrudDAO crudDAO = getDaoFactory().getCrudDAO();
			crudDAO.setPersistentClass(MdmDictionaries.class);
			Transaction tx=crudDAO.beginTransaction();
			if(dctType ==null || dctCode==null ){
				setErrorCode(-2);
				setErrorDesc("Dictionary code or Dictionary Type is null");
				return ;
			}
			List criterion = new ArrayList();
			criterion.add(Restrictions.eq("dct_type", dctType));
			criterion.add(Restrictions.eq("dct_code", dctCode));
			List result=crudDAO.findByCriterions(criterion);
			if(result==null && result.isEmpty()){
				setErrorCode(-1);
				setErrorDesc("Dictionariy type: " +dctType+ " and code: "+dctCode+" not found");
				return ;
			}
			mdmDictionaries=(MdmDictionaries)result.get(0);
			Hibernate.initialize(mdmDictionaries.getMdmDictionaries());
			if(getAttributes){
				for (MdmDctAttributes attributes : (Set<MdmDctAttributes>)mdmDictionaries.getMdmDctAttributeses()) {
					Hibernate.initialize(attributes);
				}
			}
			tx.commit();
		}catch(Exception e){
			setErrorCode(-1);
			setErrorDesc(e.getMessage());
		}
		logger.debug(methodName, "START");
		logger.debug(methodName, "END");
	}

	protected void getAttrById(){
		String methodName="getDictionariesAttributesById";
		logger.debug(methodName, "START");
		logger.debug(methodName, "END");
	}

	protected void getAttrByCodeType(){
		String methodName="getDictionariesAttributesByCodeAndType";
		logger.debug(methodName, "START");
		logger.debug(methodName, "END");
	}

	protected void getDictListByType(){
		String methodName="getDictionarieyListByType";
		logger.debug(methodName, "START");
		logger.debug(methodName, "END");
	}

	protected void saveDict(){
		String methodName="Save Dictionaries";
		logger.debug(methodName, "START");
		try{
			CrudDAO crudDAO = getDaoFactory().getCrudDAO();
			crudDAO.setPersistentClass(MdmDictionaries.class);
			if(getMdmDictionaries()==null){
				setErrorCode(-1);
				setErrorDesc("Dictionary object to save is null");
				return ;
			}
			setMdmDictionaries((MdmDictionaries)crudDAO.merge(getMdmDictionaries()));
		}catch(Exception e){
			setErrorCode(-1);
			setErrorDesc(e.getMessage());
		}


		logger.debug(methodName, "END");
	}

	protected void saveAttr(){
		String methodName="Save Attributes";
		logger.debug(methodName, "START");
		try{
			CrudDAO crudDAO = getDaoFactory().getCrudDAO();
			crudDAO.setPersistentClass(MdmDctAttributes.class);
			if(getMdmAttributes()==null){
				setErrorCode(-1);
				setErrorDesc("Dictionary attributes object to save is null");
				return ;
			}
			setMdmAttributes((MdmDctAttributes)crudDAO.merge(getMdmAttributes()));
		}catch(Exception e){
			setErrorCode(-1);
			setErrorDesc(e.getMessage());
		}

		logger.debug(methodName, "END");
	}

	public Long getDictId() {
		return dictId;
	}

	public void setDictId(Long dictId) {
		this.dictId = dictId;
	}

	public String getDctType() {
		return dctType;
	}

	public void setDctType(String dctType) {
		this.dctType = dctType;
	}

	public String getDctCode() {
		return dctCode;
	}

	public void setDctCode(String dctCode) {
		this.dctCode = dctCode;
	}

	public String getDctAttrName() {
		return dctAttrName;
	}

	public void setDctAttrName(String dctAttrName) {
		this.dctAttrName = dctAttrName;
	}

	public MdmDictionaries getMdmDictionaries() {
		return mdmDictionaries;
	}

	public MdmDctAttributes getMdmAttributes() {
		return mdmAttributes;
	}

	public List<MdmDictionaries> getMdmDictList() {
		return mdmDictList;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public void setGetAttributes(boolean getAttributes) {
		this.getAttributes = getAttributes;
	}

	public void setMdmDictionaries(MdmDictionaries mdmDictionaries) {
		this.mdmDictionaries = mdmDictionaries;
	}

	public void setMdmAttributes(MdmDctAttributes mdmAttributes) {
		this.mdmAttributes = mdmAttributes;
	}



}
